﻿using System;
using System.Web;
using blackhouse.BlackApart.Business;
using blackhouse.BlackApart.Web;
using System.Web.UI.HtmlControls;
using mojoPortal.Web;
using mojoPortal.Web.Framework;
using mojoPortal.Business;
using mojoPortal.Business.WebHelpers;
using System.Text;
using System.Data;

namespace blackhouse.Aparts.Web.Handlers {
	public class ApartmentCityRewriteModule : IHttpModule {
		#region IHttpModule Members

		public void Dispose() {
		}

		public void Init(HttpApplication context) {
			context.BeginRequest += new EventHandler(context_BeginRequest);
			//context.PostMapRequestHandler += new EventHandler(context_PostMapRequestHandler);
		}

		#endregion

		public void context_BeginRequest(object sender, EventArgs e) {
			HttpContext context = ((HttpApplication)sender).Context;
			string originalUrl = context.Request.RawUrl;
			string evF = Factory.Instance().GetPreFolderEvaluation();
			if (!string.IsNullOrEmpty(evF))
				originalUrl = originalUrl.ReplaceEx(evF, "");
			originalUrl = originalUrl.Trim('/');

			if (originalUrl.StartsWith(HttpContext.GetGlobalResourceObject("Aparts", "apartmentsUrl").ToString() + '-')) {
				originalUrl = UrlUtils.LocalizeUrl("/pages/apartments.aspx");
				context.RewritePath("~" + originalUrl, string.Empty, string.Empty, true);

				context.Items["ChangeFormAction"] = originalUrl;
			}
		}

		public void context_PostMapRequestHandler(object sender, EventArgs e) {
			HttpContext context = ((HttpApplication)sender).Context;
			if (context.Items.Contains("ChangeFormAction")) {
				System.Web.UI.Page page = context.Handler as System.Web.UI.Page;
				if (page != null && page.Form != null) {
					page.Form.Load += new EventHandler(Form_Load);
				}
			}
		}

		public void Form_Load(object sender, EventArgs e) {
			HttpContext context = ((HttpApplication)sender).Context;
			HtmlForm form = sender as HtmlForm;
			form.Action = context.Items["ChangeFormAction"].ToString();
		}














		protected void UrlRewriter_BeginRequest(object sender, EventArgs e) {
			if (sender == null) return;

			HttpApplication app = (HttpApplication)sender;


			if (!WebConfigSettings.UseUrlReWritingForStaticFiles) {

				if (WebUtils.IsRequestForStaticFile(app.Request.Path)) { return; }

				if (
					  (app.Request.Path.EndsWith("csshandler.ashx", StringComparison.InvariantCultureIgnoreCase))
						|| (app.Request.Path.EndsWith("CaptchaImage.ashx", StringComparison.InvariantCultureIgnoreCase))
						|| (app.Request.Path.EndsWith("/Data/", StringComparison.InvariantCultureIgnoreCase))
						|| (app.Request.Path.StartsWith("/Data/", StringComparison.InvariantCultureIgnoreCase))
						) {
					return;

				}
			}

			if (WebConfigSettings.UseUrlReWriting) {
				try {
					RewriteUrl(app);
				}
				catch (InvalidOperationException ex) {

				}
				catch (System.Data.Common.DbException ex) {

				}
				catch (Exception ex) {
					// hate to trap System.Exception but SqlCeException doe snot inherit from DbException as it should
					if (DatabaseHelper.DBPlatform() != "SqlCe") { throw ex; }
				}


			}
		}

		private static void RewriteUrl(HttpApplication app) {
			if (app == null) return;

			string requestPath = app.Request.Path;

			bool useFolderForSiteDetection = WebConfigSettings.UseFoldersInsteadOfHostnamesForMultipleSites;

			string virtualFolderName;
			if (useFolderForSiteDetection) {
				virtualFolderName = VirtualFolderEvaluator.VirtualFolderName();
			}
			else {
				virtualFolderName = string.Empty;
			}

			bool setClientFilePath = true;


			if (
				(useFolderForSiteDetection)
				&& (virtualFolderName.Length > 0)
				) {
				setClientFilePath = false;

				// requesting root of folderbased site like /folder1/
				// don't re-write it
				if (requestPath.EndsWith(virtualFolderName + "/")) {
					return;
				}
			}



			// Remove extended information after path, such as for Web services 
			// or bogus /default.aspx/default.aspx
			string pathInfo = app.Request.PathInfo;
			if (pathInfo != string.Empty) {
				requestPath = requestPath.Substring(0, requestPath.Length - pathInfo.Length);
			}

			// 2006-01-25 : David Neal : Updated URL checking, Fixes for sites where mojoPortal 
			// is running at the root and for bogus default document URLs
			// Get the relative target URL without the application root
			string appRoot = WebUtils.GetApplicationRoot();

			if (requestPath.Length == appRoot.Length) { return; }

			string targetUrl = requestPath.Substring(appRoot.Length + 1);
			//if (targetUrl.Length == 0) return;
			if (StringHelper.IsCaseInsensitiveMatch(targetUrl, "default.aspx")) return;

			if (useFolderForSiteDetection) {
				if (targetUrl.StartsWith(virtualFolderName + "/")) {
					// 2009-03-01 Kris reported a bug where folder site using /er for the folder
					// was making an incorrect targetUrl 
					// this url from an edit link in feed manager http://localhost/er/FeedManager/FeedEdit.aspx?mid=54&pageid=34
					// was getting changed to http://localhost/er/FeedManagFeedEdit.aspx?mid=54&pageid=34 causig a 404
					// caused by this commented line
					//targetUrl = targetUrl.Replace(virtualFolderName + "/", string.Empty);
					//fixed by changing to this
					targetUrl = targetUrl.Remove(0, virtualFolderName.Length + 1);

				}
			}


			if (!WebConfigSettings.Disable301Redirector) {
				try {
					// check if the requested url is supposed to redirect
					string redirectUrl = GetRedirectUrl(targetUrl);
					if (redirectUrl.Length > 0) {
						Do301Redirect(app, redirectUrl);
						return;
					}
				}
				catch (NullReferenceException ex) {
					// this can happen on a new installation so we catch and log it
				}
			}


			FriendlyUrl friendlyUrl = null;
			SiteSettings siteSettings = CacheHelper.GetCurrentSiteSettings();
			//this will happen on a new installation
			if (siteSettings == null) { return; }

			if (
			(useFolderForSiteDetection)
			&& (virtualFolderName.Length > 0)
			) {

				//int siteID = SiteSettings.GetSiteIDFromFolderName(virtualFolderName);
				friendlyUrl = new FriendlyUrl(siteSettings.SiteId, targetUrl);
			}
			else {
				if (siteSettings.DefaultFriendlyUrlPattern == SiteSettings.FriendlyUrlPattern.PageName) {
					//when using extensionless urls we consistently store them without a trailing slash
					if (targetUrl.EndsWith("/")) {

						targetUrl = targetUrl.Substring(0, targetUrl.Length - 1);
						setClientFilePath = false;
					}
				}

				if (WebConfigSettings.AlwaysUrlEncode) {
					friendlyUrl = new FriendlyUrl(WebUtils.GetHostName(), HttpUtility.UrlEncode(targetUrl));

					//in case existing pages are not url encoded since this setting was added 2009-11-15, try again without encoding

					if (!friendlyUrl.FoundFriendlyUrl) {
						if (WebConfigSettings.RetryUnencodedOnUrlNotFound) {
							friendlyUrl = new FriendlyUrl(WebUtils.GetHostName(), targetUrl);
						}
					}

				}
				else {
					friendlyUrl = new FriendlyUrl(WebUtils.GetHostName(), targetUrl);
				}
			}

			if (
				(friendlyUrl == null)
				|| (!friendlyUrl.FoundFriendlyUrl)
				) {
				if (
				(useFolderForSiteDetection)
				&& (virtualFolderName.Length > 0)
				) {
					SiteUtils.TrackUrlRewrite();

					//2009-03-01 same bug as above
					//string pathToUse = requestPath.Replace(virtualFolderName + "/", string.Empty);
					string pathToUse = requestPath.Remove(0, virtualFolderName.Length + 1);

					// this is a flag that can be used to detect if the url was already rewritten if you need to run a custom url rewriter after this one
					// you should only rewrite urls that were not rewritten by mojoPortal url rewriter
					app.Context.Items["mojoPortaLDidRewriteUrl"] = true;

					app.Context.RewritePath(
						pathToUse,
						string.Empty,
						app.Request.QueryString.ToString(),
						setClientFilePath);

				}
				else {
					if ((targetUrl.Length > 1) && (!targetUrl.Contains("."))) {
						// this is a flag that will be detected in our pagenotfoundhttpmodule
						// so we can handle 404 for extensionless urls
						app.Context.Items["UrlNotFound"] = true;
					}
					return;
				}


			}

			string queryStringToUse = string.Empty;
			string realPageName = string.Empty;


			if (friendlyUrl.RealUrl.IndexOf('?') > 0) {
				realPageName = friendlyUrl.RealUrl.Substring(0, friendlyUrl.RealUrl.IndexOf('?'));
				queryStringToUse = friendlyUrl.RealUrl.Substring(friendlyUrl.RealUrl.IndexOf('?') + 1);
			}
			else // Added by Christian Fredh 10/30/2006
            {
				realPageName = friendlyUrl.RealUrl;
			}


			if ((realPageName != null) && (!String.IsNullOrEmpty(realPageName))) {
				if (queryStringToUse == null) {
					queryStringToUse = String.Empty;
				}

				StringBuilder originalQueryString = new StringBuilder();

				// get any additional params besides pageid
				string separator = string.Empty;
				foreach (string key in app.Request.QueryString.AllKeys) {
					if (key != "pageid") {
						originalQueryString.Append(separator + key + "="
							+ app.Request.QueryString.Get(key));

						if (separator.Length == 0) separator = "&";

					}
				}

				if (originalQueryString.Length > 0) {
					if (queryStringToUse.Length == 0) {
						queryStringToUse = originalQueryString.ToString();
					}
					else {
						queryStringToUse += "&" + originalQueryString.ToString();
					}
				}

				SiteUtils.TrackUrlRewrite();
				//log.Info("re-writing to " + realPageName);

				// this is a flag that can be used to detect if the url was already rewritten if you need to run a custom url rewriter after this one
				// you should only rewrite urls that were not rewritten by mojoPortal url rewriter
				app.Context.Items["mojoPortaLDidRewriteUrl"] = true;

				app.Context.RewritePath(realPageName, string.Empty, queryStringToUse, setClientFilePath);
			}


		}

		/// <summary>
		/// note the expected targetUrl and returned url are not fully qualified, but relative without a /
		/// </summary>
		/// <param name="targetUrl"></param>
		/// <returns></returns>
		private static string GetRedirectUrl(string targetUrl) {
			//lookup if this url is to be redirected, if found return the new url
			string newUrl = string.Empty;

			SiteSettings siteSettings = CacheHelper.GetCurrentSiteSettings();
			using (IDataReader reader = RedirectInfo.GetBySiteAndUrl(siteSettings.SiteId, targetUrl)) {
				if (reader.Read()) {
					newUrl = reader["NewUrl"].ToString();
				}
			}

			return newUrl;
		}

		private static void Do301Redirect(HttpApplication app, string newUrl) {

			string siteRoot = SiteUtils.GetNavigationSiteRoot();

			app.Context.Response.Status = "301 Moved Permanently";
			if (WebConfigSettings.PassQueryStringFor301Redirects) {
				app.Context.Response.AddHeader("Location", siteRoot + "/" + newUrl + app.Request.Url.Query);
			}
			else {
				app.Context.Response.AddHeader("Location", siteRoot + "/" + newUrl);
			}

		}


	}
}
